<?php

require_once APPPATH . 'dao/configurationManager.php';

class manageLayer extends CI_Controller {

    function __construct() {
        parent::__construct();
    }

    public function index($layer = '',$isUpdate = FALSE) {
        if ($this->session->userdata('logged_in')) {
            
                $this->loadInitView($layer,$isUpdate);
        } else {
            redirect('/login');
        }
    }

    private function loadInitView($layer,$isUpdate, $errors = null) {
        
        $data = array();
        if ($layer === '') {
            

            $data['layer'] = $layer;

            add_js(array(
                'assets/libs/jqGrid/js/jquery.jqGrid.min.js',
                'assets/libs/jqGrid/js/i18n/grid.locale-es.js',
                'assets/libs/Openlayers/OpenLayers.js',
                'assets/js/selectWMSLayer.js',
            ));
            add_css(array(
                '/assets/css/selectWMSLayer.css',
                '/assets/libs/jqGrid/css/ui.jqgrid.css'
            ));
            $this->load->view('pages/header');


            $this->load->view('pages/selectWMSLayer.php', $data);

            $this->load->view('pages/footer');
        } else if($isUpdate) {
            //
            $data = $this->getDataForUpdateLayer($layer, $errors);
            
        }
        else {
            $data = $this->getDataForManageLayer($errors);
        }
        add_js(array(//'assets/libs/jqGrid/js/jquery-1.9.0.min.js',
                'assets/js/manageLayer.js',
                'assets/libs/jQueryValidate/jquery.validate.js',
                'assets/libs/jQueryValidate/additional-methods.js'
                    //'assets/libs/Openlayers/OpenLayers.js',
            ));
            add_css(array(
                '/assets/css/manageLayer.css',
                '/assets/libs/jqGrid/css/ui.jqgrid.css'
            ));
            $this->load->view('pages/header');
            $this->load->view('pages/manageLayer.php', $data);
            $this->load->view('pages/footer');
    }

    public function initManageLayer() {

        $data = $this->getDataForManageLayer();

        add_js(array(//'assets/libs/jqGrid/js/jquery-1.9.0.min.js',
            'assets/js/manageLayer.js',
            'assets/libs/jQueryValidate/jquery.validate.js',
            'assets/libs/jQueryValidate/additional-methods.js'
                //'assets/libs/Openlayers/OpenLayers.js',
        ));
        add_css(array(
            '/assets/css/manageLayer.css',
            '/assets/libs/jqGrid/css/ui.jqgrid.css'
        ));
        $this->load->view('pages/header');
        $this->load->view('pages/manageLayer.php', $data);
        $this->load->view('pages/footer');
    }

    /**
     * Eliminar una capa se pasan los parámetros por POST 
     * Se debe llamar con AJAX porque devuelve un json con la capa eliminada 
     * o bien error
     */
    public function removeLayer() {
        $tilesetName = $this->input->post('layerWMTS');
        $deleteTiles = $this->input->post('deleteTiles');
        $tileset = ConfigurationManager::getInstance()->removeLayer($tilesetName, $deleteTiles);
        if ($tileset !== FALSE && $deleteTiles) {
            $this->deleteTilesByLayer($tilesetName);
        }
        echo json_encode(array('layer' => $tilesetName));
    }

    public function perform() {

        if ($this->input->post('submit')) {
            $layer = $this->input->post('layerWMS');
            $isUpdate = $this->input->post('isUpdate');
            $srss = $this->input->post('srss');

            if ($this->validateUpdateLayer($isUpdate)) {
                // inputs de la vista

                $sourceURL = $this->input->post('WMSURL');

                $tilesetName = $this->input->post('layerWMTS');
                $sourceName = 'source_' . $this->input->post('layerWMTS');
                $transparentOP = $this->input->post('transparentOption');
                $tileFormat = $this->input->post('tileFormat');
                $enableFeature = $this->input->post('enableFeature');
                $expires = $this->input->post('expires');
                $autoExpires = $this->input->post('autoExpires');


                //Arreglo con las configuraciones de los SRS
                $srsArray = array();
                $i = 0;
                $srss = $this->input->post('srss');

                foreach ($srss as $srs) {
                    $isSRSConfigured = $this->input->post('toggleSRS-' . $srs);

                    if ($isSRSConfigured) {
                        $limitBbox = $this->input->post('limitBbox-' . $srs);
                        $limitZoom = $this->input->post('limitZoomLevels-' . $srs);
                        $srsArray[$i] = array(
                            'srs' => $srs,
                            'limitBBox' => $limitBbox,
                            'restrictedBBox' => $limitBbox ? $this->input->post('bboxMinX-' . $srs) . ' '
                                    . $this->input->post('bboxMinY-' . $srs) . ' '
                                    . $this->input->post('bboxMaxX-' . $srs) . ' '
                                    . $this->input->post('bboxMaxY-' . $srs) : '',
                            'limitZoomLevels' => $limitZoom,
                            'minZoomLevel' => $this->input->post('minZoomLevel-' . $srs),
                            'maxZoomLevel' => $this->input->post('maxZoomLevel-' . $srs)
                        );
                        $i++;
                    } else if ($isUpdate) {
                        $this->deleteTilesByLayerAndSRS($tilesetName, $srs);
                    }
                }
                if ($isUpdate) {
                    ConfigurationManager::getInstance()->updateLayer($tilesetName, $srsArray, $tileFormat, $sourceName, $sourceURL, $layer, $transparentOP, $enableFeature, $expires, $autoExpires);
                } else {
                    ConfigurationManager::getInstance()->createLayer($tilesetName, $srsArray, $tileFormat, $sourceName, $sourceURL, $layer, $transparentOP, $enableFeature, $expires, $autoExpires);
                }
                //vuelvo a la pantalla de layers
                redirect('layers');
            } else {
                $this->loadInitView($layer,$isUpdate, true);
            }
        }
    }

    /*
     * Valida los datos introducidos en el formulario mediante el uso de la librería
     * Form_validation de CodeIgniter
     */

    private function validateUpdateLayer($isUpdate) {
        // sobre el campo WMSURL hago las validaciones genericas 
        $this->form_validation->set_rules('layer', 'layer', 'xss_filter');
        $this->form_validation->set_rules('metatileX', 'metatileX', 'xss_filter');
        $this->form_validation->set_rules('metatileY', 'metatileY', 'xss_filter');
        
        $this->form_validation->set_rules('WMSURL', 'WMSURL', 'atLeastOneSRS|checkBbox|checkZoomLevels|expirationValue|clientExpirationValue');
        $this->form_validation->set_rules('layerWMTS', 'layerWMTS', 'required|uniqueLayerName[' . $isUpdate . ']');
        $this->form_validation->set_rules('transparentOption', 'transparentOption', 'xss_filter');
        $this->form_validation->set_rules('enableFeature', 'transparentOption', 'xss_filter');
        $this->form_validation->set_rules('toggleSRS-EPSG:22185', 'toggleSRS-EPSG:22185', 'xss_filter');
        $this->form_validation->set_rules('limitBbox-EPSG:22185', 'toggleSRS-EPSG:22185', 'xss_filter');
        $this->form_validation->set_rules('limitZoomLevels-EPSG:22185', 'limitZoomLevels-EPSG:22185', 'xss_filter');
        $this->form_validation->set_rules('toggleSRS-EPSG:4326', 'toggleSRS-EPSG:4326', 'xss_filter');
        $this->form_validation->set_rules('limitBbox-EPSG:4326', 'toggleSRS-EPSG:4326', 'xss_filter');
        $this->form_validation->set_rules('limitZoomLevels-EPSG:4326', 'limitZoomLevels-EPSG:4326', 'xss_filter');

        $this->form_validation->set_rules('bboxMinX-EPSG:22185', 'bboxMinX-EPSG:22185', 'xss_filter');
        $this->form_validation->set_rules('bboxMaxX-EPSG:22185', 'bboxMaxX-EPSG:22185', 'xss_filter');
        $this->form_validation->set_rules('bboxMaxY-EPSG:22185', 'bboxMaxY-EPSG:22185', 'xss_filter');
        $this->form_validation->set_rules('bboxMinY-EPSG:22185', 'bboxMinY-EPSG:22185', 'xss_filter');
        $this->form_validation->set_rules('bboxMinX-EPSG:4326', 'bboxMinX-EPSG:4326', 'xss_filter');
        $this->form_validation->set_rules('bboxMaxX-EPSG:4326', 'bboxMaxX-EPSG:4326', 'xss_filter');
        $this->form_validation->set_rules('bboxMaxY-EPSG:4326', 'bboxMaxY-EPSG:4326', 'xss_filter');
        $this->form_validation->set_rules('bboxMinY-EPSG:4326', 'bboxMinY-EPSG:4326', 'xss_filter');
        $this->form_validation->set_rules('expires', 'expires', 'xss_filter|numeric|expirationValue');
        $this->form_validation->set_rules('autoExpires', 'autoExpires', 'xss_filter|numeric|expirationValue');
        $this->form_validation->set_rules('minZoomLevel-EPSG:4326', 'minZoomLevel-EPSG:4326', 'xss_filter');
        $this->form_validation->set_rules('maxZoomLevel-EPSG:4326', 'maxZoomLevel-EPSG:4326', 'xss_filter');
        $this->form_validation->set_rules('minZoomLevel-EPSG:22185', 'minZoomLevel-EPSG:22185', 'xss_filter');
        $this->form_validation->set_rules('maxZoomLevel-EPSG:22185', 'maxZoomLevel-EPSG:22185', 'xss_filter');
        return $this->form_validation->run();
    }

    private function getDataForManageLayer($errors = null) {
        $data = array();
        $data['expires'] = isset($errors) ? set_value('expires') : ''; //$tilesetData;
        $data['autoExpires'] = isset($errors) ? set_value('autoExpires') :''; //$tilesetData;
        $data['isUpdate'] = FALSE;
        $data['trasparentOption'] = array(
            'name' => 'transparentOption',
            'id' => 'transparentOption',
            'value' => 1,
            'checked' => isset($errors) ? set_checkbox('transparentOption', 1) : 0
        );
        $data['enableFeature'] = array(
            'name' => 'enableFeature',
            'id' => 'enableFeature',
            'value' => 1,
            'checked' => isset($errors) ? set_checkbox('enableFeature', 1) : 0
        );
        /* Campo metatileX */
        $data['metatileX'] = array();

//        $data['metatileX'][1] = 2;
//        $data['metatileX'][2] = 4;
//        /* Campo metatiley */
        $data['metatileY'] = array();

//        $data['metatileY'][1] = 2;
//        $data['metatileY'][2] = 4;
        for ($i = 0; $i <= intval(MAX_METATILE); $i++) {
            $metatile = pow(2, $i);
            $data['metatileX'][$i] = $metatile;
            $data['metatileY'][$i] = $metatile;
        }
        $data['layer'] = isset($errors) ? set_value('layerWMTS') : $this->input->post('layer');
        $data['layerWMTS'] = isset($errors) ? set_value('layerWMTS') : $this->input->post('layer');
        $data['srss'] = array();
        $srssArray = is_array($this->input->post('srss')) ? $this->input->post('srss') : explode(',', $this->input->post('srss')) ;
        foreach ($srssArray as $i => $srsName) {
            $gridData = ConfigurationManager::getInstance()->getGridData($srsName);
            if (isset($gridData)) {
                $srs = array(
                    'name' => $srsName,
                    'toggleSRS' => array(
                        'name' => 'toggleSRS-' . $srsName,
                        'id' => 'toggleSRS-' . $srsName,
                        'value' => 1,
                        'checked' => isset($errors) ? set_checkbox('toggleSRS-' . $srsName, 1) : 0
                    ),
                    'limitBbox' => array(
                        'name' => 'limitBbox-' . $srsName,
                        'id' => 'limitBbox-' . $srsName,
                        'checked' => isset($errors) ? set_checkbox('limitBbox-' . $srsName, 1) : 0,
                        'value' => 1,
                        'readonly' => true
                    ),
                    'bboxMinX' => array(
                        'name' => 'bboxMinX-' . $srsName,
                        'id' => 'bboxMinX-' . $srsName,
                        'value' => isset($errors) ? set_value('bboxMinX-' . $srsName) : '',
                        'maxlength' => 20,
                        'size' => 30,
                        'readonly' => true,
                        'class' => 'bbox'
                    ),
                    'bboxMaxX' => array(
                        'name' => 'bboxMaxX-' . $srsName,
                        'id' => 'bboxMaxX-' . $srsName,
                        'value' => isset($errors) ? set_value('bboxMaxX-' . $srsName) : '',
                        'maxlength' => 20,
                        'size' => 30,
                        'readonly' => true,
                        'class' => 'bbox'
                    ),
                    'bboxMinY' => array(
                        'name' => 'bboxMinY-' . $srsName,
                        'id' => 'bboxMinY-' . $srsName,
                        'value' => isset($errors) ? set_value('bboxMinY-' . $srsName) : '',
                        'maxlength' => 20,
                        'size' => 30,
                        'readonly' => true,
                        'class' => 'bbox'
                    ),
                    'bboxMaxY' => array(
                        'name' => 'bboxMaxY-' . $srsName,
                        'id' => 'bboxMaxY-' . $srsName,
                        'value' => isset($errors) ? set_value('bboxMaxY-' . $srsName) : '',
                        'maxlength' => 20,
                        'size' => 30,
                        'readonly' => true,
                        'class' => 'bbox'
                    ),
                    'limitZoomLevels' => array(
                        'name' => 'limitZoomLevels-' . $srsName,
                        'id' => 'limitZoomLevels-' . $srsName,
                        'value' => 1,
                        'checked' => isset($errors) ? set_checkbox('limitZoomLevels-'.$srsName, 1) : 0,
                        'readonly' => true
                    ),
                    'minZoomLevel' => array(),
                    'maxZoomLevel' => array(),
                    'resolutions' => $gridData['resolutions'],
                    'units' => $gridData['units'],
                    'extent' => $gridData['extent']
                );

                for ($i = 0; $i < count($gridData['resolutions']); $i++) {
                    $srs['minZoomLevel'][$i] = $i; //. ' - ' . $gridData['resolutions'][$i];
                    $srs['maxZoomLevel'][$i] = $i; //. ' - ' . $gridData['resolutions'][$i];
                }
               
                $srs['minZoomLevelSelected'] = isset($errors) ? set_value('minZoomLevel-' . $srsName) : 0;
                $srs['maxZoomLevelSelected'] = isset($errors) ? set_value('maxZoomLevel-' . $srsName) : 0;
                
                $data['srss'][$i] = $srs;
            }
        }

        $data['WMSURL'] = $this->input->post('WMSURL'); // acá ya viene lista para inserta
       
        $data['tileImageFormats'] = ConfigurationManager::getInstance()->getImageFormats();

        $data['metatileXSelected'] = isset($errors) ?  set_value('metatileX')  : 0;
        $data['metatileYSelected'] = isset($errors) ?  set_value('metatileY')  : 0;

        $data['tileImageFormatsSelected'] = isset($errors) ? set_value('tileImageFormatsSelected') : 0;

        $data['regionPopUpAttr'] = ConfigurationManager::getInstance()->getRegionPopUpAttr();

        return $data;
    }

    /**
     * Obtiene los datos para inicializar la pantalla de modificacion de configuración de capa
     * Usa ConfigurationManager para obtenerla configuración actual
     * @param type $layer
     * @return array
     */
    private function getDataForUpdateLayer($layer, $errors = null) {
        $tilesetData = ConfigurationManager::getInstance()->getTileSetDataByName($layer);
        $sourceData = ConfigurationManager::getInstance()->getSourceDataByName((String) $tilesetData->source);

        $data = array();
        $data['isUpdate'] = TRUE;
        $data['WMSURL'] = (String) $sourceData->http->url;
        $data['srss'] = array();
        $data['layer'] = isset($errors) ? set_value('layerWMTS') : $layer;
        $data['layerWMTS'] = isset($errors) ? set_value('layerWMTS') : $layer;
        $data['expires'] = isset($errors) ? set_value('expires') :(String) $tilesetData->expires; //$tilesetData;
        $data['autoExpires'] = isset($errors) ? set_value('autoExpires') : (String) $tilesetData->auto_expire; //$tilesetData;
        $data['trasparentOption'] = array(
            'name' => 'transparentOption',
            'id' => 'transparentOption',
            'value' => 1,
            'checked' => isset($errors) ? set_checkbox('transparentOption', 1) : isset($sourceData->getmap->params->TRANSPARENT)
        );
        $data['enableFeature'] = array(
            'name' => 'enableFeature',
            'id' => 'enableFeature',
            'value' => 1,
            'checked' => isset($errors) ? set_checkbox('enableFeature', 1) : isset($sourceData->getfeatureinfo)
        );
        $srssXML = ((array) $tilesetData->xpath('grid')); // acá tengo solo los que están configurados para la capa

        $suportedSRSs = ConfigurationManager::getInstance()->getSupportedGrids();
        foreach ($suportedSRSs as $i => $supportedSRS) {
            $srsName = $supportedSRS;

            $srsXMLArray = (Array) $tilesetData->xpath('grid[. ="' . $srsName . '"]');
            $srsXML = null;
            if (!empty($srsXMLArray)) {
                $srsXML = $srsXMLArray[0];
            }
            $srsXMLAttr = isset($srsXML) ? $srsXML->attributes() : null;
            $gridData = ConfigurationManager::getInstance()->getGridData($srsName);
            $bbox = array();
            $limitedBbox = isset($errors)? set_checkbox('limitBbox-' . $srsName, 1) : false;

            if (!$limitedBbox && $srsXMLAttr && isset($srsXMLAttr['restricted_extent'])) {
                $limitedBbox = true;
            }
            $bbox = explode(' ', (String) $srsXMLAttr['restricted_extent']);

            $srs = array(
                'name' => $srsName,
                'toggleSRS' => array(
                    'name' => 'toggleSRS-' . $srsName,
                    'id' => 'toggleSRS-' . $srsName,
                    'value' => 1,
                    'checked' => isset($errors) ? set_checkbox('toggleSRS-' . $srsName, 1) : isset($srsXML)
                ),
                'limitBbox' => array(
                    'name' => 'limitBbox-' . $srsName,
                    'id' => 'limitBbox-' . $srsName,
                    'checked' => isset($errors) ? set_checkbox('limitBbox-' . $srsName, 1) : $limitedBbox,
                    'value' => 1,
                    'readonly' => true
                ),
                'bboxMinX' => array(
                    'name' => 'bboxMinX-' . $srsName,
                    'id' => 'bboxMinX-' . $srsName,
                    'value' => isset($errors) ? set_value('bboxMinX-' . $srsName) : (isset($bbox[0]) ? $bbox[0] : ''),
                    'maxlength' => 20,
                    'size' => 30,
                    'rules' => '',
                    'readonly' => true,
                    'class' => 'bbox'
                ),
                'bboxMaxX' => array(
                    'name' => 'bboxMaxX-' . $srsName,
                    'id' => 'bboxMaxX-' . $srsName,
                    'value' => isset($errors) ? set_value('bboxMaxX-' . $srsName) : (isset($bbox[2]) ? $bbox[2] : ''),
                    'maxlength' => 20,
                    'size' => 30,
                    'rules' => '',
                    'readonly' => true,
                    'class' => 'bbox'
                ),
                'bboxMinY' => array(
                    'name' => 'bboxMinY-' . $srsName,
                    'id' => 'bboxMinY-' . $srsName,
                    'value' => isset($errors) ? set_value('bboxMinY-' . $srsName) : ((isset($bbox[1]) ? $bbox[1] : '') ),
                    'maxlength' => 20,
                    'size' => 30,
                    'rules' => '',
                    'readonly' => true,
                    'class' => 'bbox'
                ),
                'bboxMaxY' => array(
                    'name' => 'bboxMaxY-' . $srsName,
                    'id' => 'bboxMaxY-' . $srsName,
                    'value' => isset($errors) ? set_value('bboxMaxY-' . $srsName) : (isset($bbox[3]) ? $bbox[3] : ''),
                    'maxlength' => 20,
                    'size' => 30,
                    'rules' => '',
                    'readonly' => true,
                    'class' => 'bbox'
                ),
                'limitZoomLevels' => array(
                    'name' => 'limitZoomLevels-' . $srsName,
                    'id' => 'limitZoomLevels-' . $srsName,
                    'value' => 1,
                    'checked' => isset($errors) ? set_checkbox('limitZoomLevels-' . $srsName, 1) : (isset($srsXMLAttr) && (isset($srsXMLAttr['minzoom']) || isset($srsXMLAttr['maxzoom']))),
                    'readonly' => true
                ),
                'minZoomLevel' => array(),
                'maxZoomLevel' => array(),
                'resolutions' => $gridData['resolutions'],
                'units' => $gridData['units'],
                'extent' => $gridData['extent']
            );

            for ($i = 0; $i < count($gridData['resolutions']); $i++) {
                $srs['minZoomLevel'][$i] = $i; // . ' - ' . $gridData['resolutions'][$i];
                $srs['maxZoomLevel'][$i] = $i; // . ' - ' . $gridData['resolutions'][$i];
            }
            $srs['minZoomLevelSelected'] = isset($srsXMLAttr['minzoom']) ? array_search(isset($errors) ? set_value('minZoomLevel-'.$srsName): (Integer) $srsXMLAttr['minzoom'], $srs['minZoomLevel']) : 0;
            $srs['maxZoomLevelSelected'] = isset($srsXMLAttr['maxzoom']) ? array_search(isset($errors) ? set_value('maxZoomLevel-'.$srsName):(Integer) $srsXMLAttr['maxzoom'], $srs['maxZoomLevel']) : 0;

            $data['srss'][$i] = $srs;
        }
        $data['tileImageFormats'] = ConfigurationManager::getInstance()->getImageFormats();
        $data['tileImageFormatsSelected'] = array_search((String) $tilesetData->format, $data['tileImageFormats']);

        /* Campo metatileX */
        $data['metatileX'] = array();

//        $data['metatileX'][1] = 2;
//        $data['metatileX'][2] = 4;
//        /* Campo metatiley */
        $data['metatileY'] = array();
//        $data['metatileY'][1] = 2;
//        $data['metatileY'][2] = 4;
        for ($i = 0; $i <= intval(MAX_METATILE); $i++) {
            $metatile = pow(2, $i);
            $data['metatileX'][$i] = $metatile;
            $data['metatileY'][$i] = $metatile;
        }

        $metatileXY = explode(' ', (String) $tilesetData->metatile);
        $data['metatileXSelected'] = isset($errors) ? set_value('metatileX') : array_search($metatileXY[0], ( $data['metatileX']));
        $data['metatileYSelected'] = isset($errors) ? set_value('metatileY') : array_search($metatileXY[1], ($data['metatileY']));


       

        $data['regionPopUpAttr'] = ConfigurationManager::getInstance()->getRegionPopUpAttr();

        return $data;
    }

    /**
     * Implementación alternativa eliminando con rm -R 
     * Debería hacerse con una llamada a mapcache_seed
     * @param type $tilesetName
     */
    private function deleteTilesByLayer($tilesetName) {

        $cachePath = ConfigurationManager::getInstance()->getCachePath();
        if ($cachePath) {
            // se ejecuta la eliminación en segundo plano

            exec('rm -R -f ' . $cachePath . '/' . $tilesetName . ' &');
        }
    }

    /**
     * Implementación alternativa eliminando con rm -R 
     * Debería hacerse con una llamada a mapcache_seed
     * @param type $tilesetName
     * @param type $srs
     */
    private function deleteTilesByLayerAndSRS($tilesetName, $srs) {

        $cachePath = ConfigurationManager::getInstance()->getCachePath();
        if ($cachePath) {
            // se ejecuta la eliminación en segundo plano

            exec('rm -R -f ' . $cachePath . '/' . $tilesetName . '/' . $srs . ' &');
        }
    }

}